from django.http import JsonResponse
from django.shortcuts import render
import pickle, base64
from django.views import View
from django_redis import get_redis_connection

from apps.goods.models import SKU
from utils.transformJson import TransformJson


class CartsView(View):
    def post(self, request):
        data = TransformJson(request)
        sku_id = data.get('sku_id')
        count = data.get('count')
        try:
            SKU.objects.get(id=sku_id)
        except SKU.DoesNotExist:
            return JsonResponse({'code': 400, 'errmsg': "参数不全"})

        try:
            count = int(count)  # 数量强制转换
        except Exception:
            count = 1
        user = request.user
        if user.is_authenticated:  # 判断用户是否未认证用户
            redis_cli = get_redis_connection('carts')
            pipeline = redis_cli.pipeline()
            pipeline.hincrby('carts_%s' % user.id, sku_id, count)
            pipeline.sadd('selected_%s' % user.id, sku_id)
            pipeline.execute()
            return JsonResponse({'code': 0, 'errmsg': "ok"})
        else:
            # 判断新增商品有没有在购物车里
            cookie_carts = request.COOKIES.get('carts')
            if cookie_carts is None:  # 无数据创建新购物车
                carts = {}
            else:
                # 如果存在则进行解密操作
                carts = pickle.loads(base64.b64decode(cookie_carts))
            # 判断新增商品是否在购物车
            if sku_id in carts:
                count = carts[sku_id]['count'] + count
            carts[sku_id] = {
                'count': count,
                'selected': True,
            }
            # 数据加密并设置cookie响应
            base64encode = base64.b64encode(pickle.dumps(carts))
            response = JsonResponse({'code': 0, 'errmsg': "ok"})
            response.set_cookie('carts', base64encode.decode(), max_age=3600 * 24)
            return response

    def get(self, request):
        user = request.user
        if user.is_authenticated:  # 登录用户
            redis_cli = get_redis_connection('carts')
            sku_id_count = redis_cli.hgetall('carts_%s' % user.id)  # 得到对应key所有值
            selected_ids = redis_cli.smembers('selected_%s' % user.id)  # 得到所有的选中状态
            # 遍历判断状态并且将数据转换为和cookies一样
            # {sku_id:{count:xxx, selected: xxx},sku_id:{count:xxx, selected: xxx}}
            carts = {}
            for sku_id, count in sku_id_count.items():
                carts[int(sku_id)] = {
                    'count': int(count),
                    'selected': sku_id in selected_ids  # 判断选中状态是否在集合中
                }
        else:  # 未登录用户
            cookie_carts = request.COOKIES.get('carts')
            if cookie_carts is None:
                carts = {}
            else:
                carts = pickle.loads(base64.b64decode(cookie_carts))
        # 通用操作
        sku_ids = carts.keys()  # 获取所有外层key
        skus = SKU.objects.filter(id__in=sku_ids)
        skus_list = []
        for sku in skus:  # 拿到具体对象
            skus_list.append({
                'id': sku.id,
                'price': sku.price,
                'name': sku.name,
                'default_image_url': sku.default_image.url,
                'selected': carts[sku.id]['selected'],
                'count': carts[sku.id]['count'],
                'amount': sku.price * carts[sku.id]['count'],
            })
        return JsonResponse({'code': 0, 'errmsg': "ok", 'cart_skus': skus_list})

    def put(self, request):
        user = request.user
        data = TransformJson(request)
        sku_id = data.get('sku_id')
        count = data.get('count')
        selected = data.get('selected')
        if not all([sku_id]):
            return JsonResponse({'code': 400, 'errmsg': "参数不全"})
        try:
            SKU.objects.get(id=sku_id)
        except SKU.DoesNotExist:
            return JsonResponse({'code': 400, 'errmsg': "没有此商品"})
        try:
            count = int(count)
        except Exception:
            count = 1
        if user.is_authenticated:
            redis_cli = get_redis_connection('carts')
            redis_cli.hset('carts_%s' % user.id, sku_id, count)
            if selected:
                redis_cli.sadd('selected_%s' % user.id, sku_id)
            else:
                redis_cli.srem('selected_%s' % user.id, sku_id)
            return JsonResponse({'code': 0, 'errmsg': "ok", 'cart_sku': {'count': count, 'selected': selected}})
        else:
            cookie_carts = request.COOKIES.get('carts')
            if cookie_carts is None:
                carts = {}
            else:
                carts = pickle.loads(base64.b64decode(cookie_carts))
            if sku_id in carts:
                carts[sku_id] = {
                    'count': count,
                    'selected': selected
                }
            base64encode = base64.b64encode(pickle.dumps(carts))
            response = JsonResponse({'code': 0, 'errmsg': "ok", 'cart_sku': {'count': count, 'selected': selected}})
            response.set_cookie('carts', base64encode.decode(), max_age=3600 * 24)
            return response

    def delete(self, request):
        data = TransformJson(request)
        sku_id = data.get('sku_id')
        try:
            SKU.objects.get(id=sku_id)
        except SKU.DoesNotExist:
            return JsonResponse({'code': 400, 'errmsg': "没有此商品"})
        user = request.user
        if user.is_authenticated:
            redis_cli = get_redis_connection('carts')
            redis_cli.hdel('carts_%s' % user.id, sku_id)
            redis_cli.srem('selected_%s' % user.id, sku_id)
            return JsonResponse({'code': 0, 'errmsg': "ok"})
        else:
            cookie_carts = request.COOKIES.get('carts')
            if cookie_carts is None:
                carts = {}
            else:
                carts = pickle.loads(base64.b64decode(cookie_carts))
            del carts[sku_id]
            base64encode = base64.b64encode(pickle.dumps(carts))
            response = JsonResponse({'code': 0, 'errmsg': "ok"})
            response.set_cookie('carts', base64encode.decode(), max_age=3600 * 24)
            return response


class CartsSelectAllView(View):
    def put(self, request):
        data = TransformJson(request)
        selected = data.get('selected',True)
        # 校验参数
        if selected:
            if not isinstance(selected, bool):
                return JsonResponse({'code': 400, 'errmsg': "参数有误"})
        user = request.user
        if user.is_authenticated:
            redis_conn = get_redis_connection('carts')
            cart = redis_conn.hgetall('carts_%s' % user.id)
            sku_id_list = cart.keys()
            if selected:
                # 全选
                redis_conn.sadd('selected_%s' % user.id, *sku_id_list)
            else:
                # 取消全选
                redis_conn.srem('selected_%s' % user.id, *sku_id_list)
            return JsonResponse({'code': 0, 'errmsg': '全选购物车成功'})
        else:
            cart = request.COOKIES.get('carts')
            response = JsonResponse({'code': 0, 'errmsg': '全选购物车成功'})
            if cart is not None:
                cart = pickle.loads(base64.b64decode(cart.encode()))
                for sku_id in cart:
                    cart[sku_id]['selected'] = selected
                cookie_cart = base64.b64encode(pickle.dumps(cart)).decode()
                response.set_cookie('carts', cookie_cart, max_age=7 * 24 * 3600)
            return response
        pass


class CartsSimpleView(View):
    def get(self, request):
        # 判断用户是否登录
        user = request.user
        if user.is_authenticated:
            # 用户已登录，查询Redis购物车
            redis_conn = get_redis_connection('carts')
            redis_cart = redis_conn.hgetall('carts_%s' % user.id)
            cart_selected = redis_conn.smembers('selected_%s' % user.id)
            # 将redis中的两个数据统一格式，跟cookie中的格式一致，方便统一查询
            cart_dict = {}
            for sku_id, count in redis_cart.items():
                cart_dict[int(sku_id)] = {
                    'count': int(count),
                    'selected': sku_id in cart_selected
                }
        else:
            # 用户未登录，查询cookie购物车
            cart_str = request.COOKIES.get('carts')
            if cart_str:
                cart_dict = pickle.loads(base64.b64decode(cart_str.encode()))
            else:
                cart_dict = {}
        cart_skus = []
        sku_ids = cart_dict.keys()
        skus = SKU.objects.filter(id__in=sku_ids)
        for sku in skus:
            cart_skus.append({
                'id': sku.id,
                'name': sku.name,
                'count': cart_dict.get(sku.id).get('count'),
                'default_image_url': sku.default_image.url
            })

        # 响应json列表数据
        return JsonResponse({'code': 0, 'errmsg': 'OK', 'cart_skus': cart_skus})
